package com.katesoft.scale4j.persistent.spring.postprocessor;

import static com.katesoft.scale4j.common.services.IBeanNameReferences.TRANSACTION_SERVICE;
import static com.katesoft.scale4j.common.spring.IPostProcessingOrder.TRANSACTION_POST_PROCESSOR_PRIORITY;

import java.util.Properties;

import net.jcip.annotations.ThreadSafe;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
import org.springframework.core.Ordered;

import com.katesoft.scale4j.common.spring.AbstractBeanPropertiesOverridePostProcessor;

/**
 * This post processor allows to override configuration for
 * {@link org.springframework.transaction.jta.JtaTransactionManager}, which is defined inside
 * jvmcluster persistent module.
 * 
 * @author kate2007
 */
@ThreadSafe
public class TransactionManagerConfigurationPostProcessor extends
         AbstractBeanPropertiesOverridePostProcessor implements InitializingBean, Ordered {
   private Properties transactionManagerProperties;

   public TransactionManagerConfigurationPostProcessor() {
      setTargetBean(TRANSACTION_SERVICE);
      setOrder(TRANSACTION_POST_PROCESSOR_PRIORITY);
   }

   @Override
   protected void doPostProcessing(
            @SuppressWarnings("unused") ConfigurableListableBeanFactory configurableListableBeanFactory)
            throws BeansException {
      if (transactionManagerProperties != null) {
         ValueHolder argumentValue = constructorArgumentValues
                  .getArgumentValue(0, Properties.class);
         Properties props = (Properties) argumentValue.getValue();
         logger.info("adding transactionManager properties %s to existing properties %s",
                  transactionManagerProperties, props);
         props.putAll(transactionManagerProperties);
      }
   }

   @Override
   public void afterPropertiesSet() {
      logger.info(
               "Using TransactionManagerBeanName = %s, transactionManagerProperties = %s for post processing",
               getTargetBean(), transactionManagerProperties);
   }

   public void setTransactionManagerProperties(final Properties transactionManagerProperties) {
      this.transactionManagerProperties = transactionManagerProperties;
   }
}
